﻿Option Explicit On
'*******************************************************************
' Program: pkgVisio
' Author: Albert E Edlund
' Date:
'
' Purpose:
' Working with office object XML
'
'*******************************************************************


#Region " imports "

Imports System
Imports System.Object
Imports System.IO
Imports System.IO.TextReader
' need to reference windowsbase in .net
Imports System.IO.Packaging

' need for dbconnectionstringbuilder used in clsConnections
Imports System.Data.Common

Imports System.Windows
Imports System.Windows.Forms
Imports System.Text.StringBuilder

Imports Microsoft.VisualBasic

Imports System.Text
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.ObjectModel

Imports System.Xml
Imports System.Linq
Imports System.Linq.Enumerable
Imports System.Windows.Input

Imports System.Xml.Serialization
Imports System.Xml.Linq
Imports System.Xml.XPath

Imports ADODB
Imports System.Data
Imports System.Data.OleDb
Imports System.Data.Sql


Imports Microsoft.Practices.EnterpriseLibrary.Common
Imports Microsoft.Practices.EnterpriseLibrary.ExceptionHandling
Imports Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging


' visio v15 does not use a xName prefix which may put it into conflict with other open office apps
Imports <xmlns="http://schemas.microsoft.com/office/visio/2012/main">
Imports <xmlns:rs="urn:schemas-microsoft-com:rowset">

' generic namespace for office open xml, used in all of them
Imports <xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">

Imports pkgVisio.clsVisPackage
Imports pkgVisio.clsStructures

#End Region



'**********************************************************************************
' class connections is the data connection information used by the recordsets
' the connections package part is read and saved as a collection and optionally will
' handle a referenced listview control
'**********************************************************************************

Public Class clsConnections



#Region " Properties and Declarations "


    Public Structure dataConn
        Public connId As String
        Public connFile As String
        Public connString As String
        Public connTimeout As String

        Public Sub New _
            (ByVal connId As String, _
             ByVal connFile As String, _
             ByVal connString As String, _
             ByVal connTimeout As String)

            Me.connId = connId
            Me.connFile = connFile
            Me.connString = connString
            Me.connTimeout = connTimeout
        End Sub

    End Structure


    '
    ' pkgpartInfo is the collection of content and file pointers in the package
    '
    Private m_colPkgPartInfo As Collection(Of pkgpartInfo)
    Public Property colPkgPartInfo As Collection(Of pkgpartInfo)
        Get
            colPkgPartInfo = Me.m_colPkgPartInfo
        End Get
        Set(value As Collection(Of pkgpartInfo))
            If (value Is Nothing) Then
                Throw New System.ArgumentNullException("Value", _
                    "colPkgPartsInfo is Null.")
            End If
            Me.m_colPkgPartInfo = value
        End Set
    End Property

    '
    ' what is the latest document
    '
    Public m_xDoc As XDocument
    Public Property xDoc As XDocument
        Get
            Return Me.m_xDoc
        End Get
        Set(value As XDocument)
            If (value Is Nothing) Then
                Throw New System.ArgumentNullException("Value", _
                    "xDoc is Null.")
            End If
            Me.m_xDoc = value
        End Set
    End Property

    '
    '
    '
    Private m_fileCurrent As String
    Public Property fileCurrent As String
        Get
            fileCurrent = Me.m_fileCurrent
        End Get
        Set(value As String)
            If ((value Is Nothing) Or (value = "")) Then
                Throw New System.ArgumentNullException("Value", _
                    "fileCurrent is Null.")
            End If
            Me.m_fileCurrent = value
        End Set
    End Property

    '
    '
    '
    Private m_dictDataConn As Dictionary(Of Long, dataConn)
    Public Property dictDataConn As Dictionary(Of Long, dataConn)
        Get
            dictDataConn = Me.m_dictDataConn
        End Get
        Set(value As Dictionary(Of Long, dataConn))
            If (value Is Nothing) Then
                Throw New System.ArgumentNullException("Value", _
                    "dictDataConn is Null.")
            End If
            Me.m_dictDataConn = value
        End Set
    End Property


#End Region


    '
    ' pass in a listview control and load it with the datarecordsets
    '
    Public Sub loadDataConnections _
                (ByRef lvControl As ListView)

        Dim strConnId As String = "-1"
        Dim strConnFileName As String = ""
        Dim strConnString As String = ""
        Dim strConnTimeout As String = ""
        Dim lvItem As ListViewItem

        If Me.m_dictDataConn Is Nothing Then
            dictDataConn = New Dictionary(Of Long, dataConn)
        End If
        Me.dictDataConn.Clear()

        Try

            If lvControl IsNot Nothing Then
                lvControl.Items.Clear()
                lvControl.Columns.Clear()
                lvControl.View = View.Details
                lvControl.AllowColumnReorder = True
                lvControl.FullRowSelect = True
                lvControl.Columns.Add("Id", 40, HorizontalAlignment.Right)
                lvControl.Columns.Add("File", 100, HorizontalAlignment.Left)
                lvControl.Columns.Add("ConnStr", 200, HorizontalAlignment.Left)
                lvControl.Columns.Add("T/O", 50, HorizontalAlignment.Right)
            End If


            Dim qryConnections = Me.xDoc...<DataConnection>
            Dim intConnections As Integer = qryConnections.Count

            For Each connection In qryConnections

                strConnId = "-1"
                strConnFileName = "NoFile"
                strConnString = "NoConnString"
                strConnTimeout = "NoTimeout"

                Dim listOfAttributes As IEnumerable(Of XAttribute) = _
                    From att In connection.Attributes() _
                    Select att

                For Each att As XAttribute In listOfAttributes
                    ' Console.WriteLine("{0}={1}", att.Name.LocalName, att.Value)
                    Select Case LCase(att.Name.LocalName)
                        Case "id"
                            strConnId = att.Value
                        Case "filename"
                            strConnFileName = att.Value
                        Case "connectionstring"
                            strConnString = att.Value
                        Case "timeout"
                            strConnTimeout = att.Value
                    End Select
                Next att

                ' break the fields out of the connection string
                ' readConnectionString(strConnString)

                Dim itemConn As dataConn = New dataConn _
                            (strConnId, _
                             strConnFileName, _
                             strConnString, _
                             strConnTimeout)
                dictDataConn.Add(CLng(strConnId), itemConn)

                If lvControl IsNot Nothing Then

                    lvItem = New ListViewItem(strConnId)
                    lvItem.SubItems.Add(strConnFileName)
                    lvItem.SubItems.Add(strConnString)
                    lvItem.SubItems.Add(strConnTimeout)

                    ' add it to the listview on the data page
                    lvControl.Items.Add(lvItem)
                End If ' test for lvcontrol valid
            Next connection


        Catch errXml As XmlException
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(errXml, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try

    End Sub

    '
    ' 
    '
    Public Function getDataConnection(ByVal strId As String) As dataConn


        Dim connReturn As dataConn = New dataConn("", "", "", "")

        Try

            ' first check for a v2007/v12 implementation
            Dim qryDataConnection = From dataconnSel In Me.xDoc...<DataConnection>
                Where dataconnSel.@ID = strId

            Dim intConnection As Integer = qryDataConnection.Count


            Dim strConnId As String = ""
            Dim strConnFile As String = ""
            Dim strConnString As String = ""
            Dim strConnTimeout As String = ""


            ' first the attributes for the cell
            Dim listOfAttributes As IEnumerable(Of XAttribute) = _
                From att In qryDataConnection.Attributes() _
                Select att

            For Each att As XAttribute In listOfAttributes
                'Debug.Print("Att {0}={1}", att.Name.LocalName, att.Value)
                Select Case LCase(att.Name.LocalName)
                    Case "id"
                        strConnId = att.Value
                    Case "filename"
                        strConnFile = att.Value
                    Case "connectionstring"
                        strConnString = att.Value
                    Case "timeout"
                        strConnTimeout = att.Value
                End Select
            Next att

            With connReturn
                .connId = strConnId
                .connFile = strConnFile
                .connString = strConnString
                .connTimeout = strConnTimeout
            End With


        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try


        getDataConnection = connReturn

    End Function


    '
    ' pass in a connection string and return the keys and values
    '
    Public Function readConnectionString(ByVal connString As String) As String

        Dim strBuilder As StringBuilder = New StringBuilder
        Dim builder As DbConnectionStringBuilder = New DbConnectionStringBuilder
        builder.ConnectionString = connString

        Dim intX As Integer
        For intX = 0 To builder.Count - 1
            strBuilder.AppendFormat("{0} = {1}" & vbCrLf, builder.Keys(intX), builder.Values(intX))
        Next intX


        readConnectionString = strBuilder.ToString

    End Function


    '
    '
    '
    Public Sub New()

        If Me.dictDataConn Is Nothing Then
            Me.dictDataConn = New Dictionary(Of Long, dataConn)
        End If
        dictDataConn.Clear()
        If Me.colPkgPartInfo Is Nothing Then
            Me.colPkgPartInfo = New Collection(Of pkgpartInfo)
        End If
        colPkgPartInfo.Clear()
        If Me.xDoc Is Nothing Then
            Me.xDoc = New XDocument
        End If


    End Sub

    '
    '
    '
    Protected Overrides Sub Finalize()

        'If Me.m_dictDataConn IsNot Nothing Then
        '    Me.m_dictDataConn = Nothing
        'End If

        'If Me.m_colPkgPartInfo IsNot Nothing Then
        '    Me.m_colPkgPartInfo = Nothing
        'End If

        'If Me.m_xDoc IsNot Nothing Then
        '    Me.m_xDoc = Nothing
        'End If

        MyBase.Finalize()
    End Sub

End Class
